<?php
// no direct access
defined('_JEXEC') or die;
jimport('joomla.application.component.helper');

/**
 * BP Load Snippet - Joomla Plugin to override core content creating classes during content creation
 * to search for and replace markers to load particular code snippets.
 * 
 * @author Brian Bolli
 *
 */

class plgContentBPLoadSnippet extends JPlugin
{
	protected static $snippets = array();
	protected static $loadScripts = array();
	private $scriptFiles = array(	"as"			=> "shBrushAppleScript.js",
									"as3"			=> "shBrushAS3.js",
									"bash"			=> "shBrushBash.js",
									"coldfusion"	=> "shBrushColdFusion.js",
									"cpp"			=> "shBrushCpp.js",
									"csharp"		=> "shBrushCSharp.js",
									"css"			=> "shBrushCss.js",
									"pascal"		=> "shBrushDelphi.js",
									"diff"			=> "shBrushDiff.js",
									"erlang"		=> "shBrushErland.js",
									"groovy"		=> "shBrushGroovy.js",
									"java"			=> "shBrushJava.js",
									"javafx"		=> "shBrushJavaFX.js",
									"javascript"	=> "shBrushJScript.js",
									"perl"			=> "shBrushPerl.js",
									"php"			=> "shBrushPhp.js",
									"text"			=> "shBrushPlain.js",
									"plain"			=> "shBrushPlain.js",
									"powershell"	=> "shBrushPowerShell.js",
									"python"		=> "shBrushPython.js",
									"ruby"			=> "shBrushRuby.js",
									"sass"			=> "shBrushSass.js",
									"scala"			=> "shBrushScala.js",
									"sql"			=> "shBrushSql.js",
									"vb"			=> "shBrushVb.js",
									"xml"			=> "shBrushXml.js"
	);
	
	/**
	 * Plugin that loads code snippets within content
	 *
	 * @param	string	The context of the content being passed to the plugin.
	 * @param	object	The article object.  Note $article->text is also available
	 * @param	object	The article params
	 * @param	int		The 'page' number
	 */
	public function onContentPrepare($context, &$article, &$params, $page = 0)
	{
		$doc = JFactory::getDocument();
		// Don't run this plugin when the content is being indexed
		if ($context == 'com_finder.indexer') {
			return true;
		}

		// simple performance check to determine whether bot should process further
		if (strpos($article->text, 'LoadSnippet') === false && strpos($article->text, 'LoadSnippet') === false) {
			return true;
		}

		// expression to search for snippets
		$regex		= "/\{LoadSnippet\s+[0-9]+\}/";
	
		// Find all instances of plugin and put in $matches for loadposition
		// $matches[0] is full pattern match, $matches[1] is the position
		preg_match_all($regex, $article->text, $matches, PREG_SET_ORDER);
		// No matches, skip this
		if ($matches) {
			$doc->addScript(JUri::root() . 'media/com_bpsyntaxhighlighter/syntax-highlighter/scripts/XRegExp.js');
			$doc->addScript(JUri::root() . 'media/com_bpsyntaxhighlighter/syntax-highlighter/scripts/shCore.js');
			//$doc->addScript(JUri::root() . 'media/com_bpsyntaxhighlighter/syntax-highlighter/scripts/shBrushPlain.js');
			foreach ($matches as $match) {
				foreach ($match as $m) {
					$snippet = (string) trim($m);
					$snippet = str_replace("{LoadSnippet ", "", $snippet);
					$snippet = str_replace("}", "", $snippet);
					$output = $this->_loadSnippet($snippet);
					$article->text = preg_replace("|$m|", addcslashes($output, '\\$'), $article->text, 1);
				}
			}
			$doc->addStyleSheet(Juri::root() . 'media/com_bpsyntaxhighlighter/css/plg_bploadsnippet.css');
			$doc->addStyleSheet(Juri::root() . 'media/com_bpsyntaxhighlighter/syntax-highlighter/styles/shCore.css');
			$doc->addStyleSheet(Juri::root() . 'media/com_bpsyntaxhighlighter/syntax-highlighter/styles/shThemeDefault.css');
		}
	}

	/**
	 * _loadSnippet - method taking a primary key reference and styling option (future) and return wrapped formatted code 
	 * 
	 * @param integer $snippet_id - key to code snippet in database
	 * @param string $style - For Future integration of styling options provided by Syntax Highlighter library
	 * @return string - code snippet from database
	 */
	
	protected function _loadSnippet($snippet_id, $style = 'none')
	{
		$doc = JFactory::getDocument();
		$output = '';
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select("*");
		$query->from("#__bpsyntaxhighlighter_snippets");
		$query->where("id=" . (int) $snippet_id);
		$db->setQuery($query);
		$db->query();
		$html = $db->loadAssoc();
				
		$params = new JRegistry;
		$params->loadJSON($html['params']);
		
		if ($brush = $this->scriptFiles[strtolower($params->get('brush'))]) :
			$doc->addScript(JUri::root() . "media/com_bpsyntaxhighlighter/syntax-highlighter/scripts/" . $brush);
			ob_start();
			$method = str_replace(".js", "", $brush);
			$method = str_replace("shBrush", "", $method);
			$output = self::_wrapSnippet($html['description'], $method);
			$output = ob_get_clean();
		endif;
		return $output;
	}
	
	/**
	 * _wrapSnippet - Wrap raw code snippet from database in script element and attach required javascript.  
	 * Retruned ready to be inserted code snippet.
	 * 
	 * @param string $html - raw code snippet from database
	 * @param string $params
	 * @param string $method - brush to be applied to code snippet
	 * @return string
	 */
	
	protected function _wrapSnippet($html, $method) {
		$return = "<div class=\"bp-wrapper\">\n<script type=\"syntaxhighlighter\" class=\"brush: " . strtolower($method) . ";\"><![CDATA[\n" . $html . "\n]]></script>\n</div>\n" . $this->_buildScript();
		echo $return;
		return $return;
	}
	

	/**
	 * _buildScript - utility script to build global paramters and wraps in script declaration to insert.
	 * 
	 * @return string
	 */
	protected function _buildScript() {
		$params = &JComponentHelper::getParams('com_bpsyntaxhighlighter');
		$html  = "<script type=\"text/javascript\">\n";
		$html .= "SyntaxHighlighter.config.clipboardSwf = \"http://dev.binarypursuits.com/media/com_bpsyntaxhighlighter/syntax-highlighter/scripts/clipboard.swf\";\n";
		$html .= "SyntaxHighlighter.defaults[\"auto_links\"] = " . $params->get('auto_links') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"collapse\"] = " . $params->get('collapse') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"first_line\"] = " . $params->get('first_line') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"gutter\"] = " . $params->get('gutters') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"highlight\"] = " . $params->get('highlight') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"html_script\"] = " . $params->get('html_script') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"smart_tabs'\"] = " . $params->get('smart_tabs') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"tab_size\"] = " . $params->get('tab_size') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"smart_tabs\"] = " . $params->get('smart_tabs') . ";\n";
		$html .= "SyntaxHighlighter.defaults[\"toolbar\"] = " . $params->get('toolbar') . ";\n";
		$html .= "SyntaxHighlighter.all();\n";
		$html .= "</script>\n";
		return $html;
	}
}
	
	
